import { defineComponent, Ref, ref } from "vue";
import G6Editor from "@antv/g6-editor";
import "./index.less";
import { graphCfg, flowCfg, modeCfg, EvTypes } from "./typing";
import { Col, Row } from "ant-design-vue";
import ToolbarPannel from "./ToolbarPannel";
import ItemPannel from "./ItemPannel";

const modes: modeCfg = {
  default: [
    "panBlank",
    "hoverGroupActived",
    "keydownCmdWheelZoom",
    "clickEdgeSelected",
    "clickNodeSelected",
    "clickCanvasSelected",
    "clickGroupSelected",
    "hoverNodeActived",
    "hoverEdgeActived",
    "hoverAnchorActived",
    "hoverButton",
    "clickCollapsedButton",
    "clickExpandedButton",
    "wheelPanCanvas",
    "keydownShiftMultiSelected",
    "dragNodeAddToGroup",
    "dragOutFromGroup",
    "panItem",
    "hoverEdgeControlPoint",
  ],
  add: ["dragPanelItemAddNode", "dragAnchorAddEdge"],
  resize: ["dragEdgeControlPoint", "hoverEdgeControlPoint"],
  readOnly: ["panCanvas"],
  move: ["panCanvas"],
  multiSelect: ["dragMultiSelect"],
};

export default defineComponent({
  props: {
    id: {
      type: String,
      default: "",
    },
  },
  setup() {
    const toolbarRef: Ref<HTMLElement | null> = ref(null);
    const itemRef: Ref<HTMLElement | null> = ref(null);
    const pageRef: Ref<HTMLElement | null> = ref(null);
    const detailRef: Ref<HTMLElement | null> = ref(null);

    G6Editor.track(false);
    const editor = new G6Editor();

    return {
      editor,
      toolbarRef,
      itemRef,
      pageRef,
      detailRef,
    };
  },
  data() {
    return {
      nodeId: "canvas",
      toolbarPannel: null as G6Editor.Toolbar | null,
      detailPannel: null as G6Editor.Detailpannel | null,
      itemPannel: null as G6Editor.Itempannel | null,
      flow: null as G6Editor.Flow | null,
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.init();
    });
  },
  methods: {
    init() {
      this.toolbarPannel = new G6Editor.Toolbar({ container: this.toolbarRef });
      this.itemPannel = new G6Editor.Itempannel({ container: this.itemRef });
      this.detailPannel = new G6Editor.Detailpannel({
        container: this.detailRef,
      });
      const _g_cfg: flowCfg = {
        container: this.pageRef,
        modes: modes,
        mode: "default",
      };
      const editCfg: graphCfg = {
        graph: _g_cfg,
        noEndEdge: false,
      };

      this.flow = new G6Editor.Flow(editCfg);
      // 设置边为圆角直线
      this.flow.changeAddEdgeModel({ shape: "flow-polyline-round" });

      const graph = this.flow.getGraph();
      graph.setFitView("cc");
      this.editor.add(this.toolbarPannel);
      this.editor.add(this.itemPannel);
      this.editor.add(this.detailPannel);
      this.editor.add(this.flow);
      this.eventSetting();
    },
    eventSetting() {
      const graph = this.flow?.getGraph();
      if (!graph || !this.flow) {
        return;
      }
      // 点击节点
      graph.on("node:click", (ev: EvTypes) => {
        this.nodeId = ev.item.model.id;
      });
      // 点击边
      graph.on("edge:click", (ev: EvTypes) => {
        this.nodeId = ev.item.model.id;
      });
      // 点击画布
      graph.on("click", (ev: EvTypes) => {
        console.log(ev);
        this.nodeId = "canvas";
      });
      this.flow.on("hovernode:beforeshowanchor", (ev: EvTypes) => {
        // 结束节点不能够引出连线
        if (ev.item.model.name === "end") {
          ev.cancel = true;
          return;
        }
        // 当开始节点存在一条连线的时候，不应再引出一条边线
        if (ev.item.model.name === "start") {
          if (ev.item.getEdges().length > 0) {
            ev.cancel = true;
          }
        }
      });
      // 当节点在拖动的时候，如果是它本身或是开始节点，则不能向其引边线
      this.flow.on("dragedge:beforeshowanchor", (ev: EvTypes) => {
        if (ev.source.id === ev.target.id) {
          ev.cancel = true;
          return;
        }
        const node = this.flow?.find(ev.target.id).model;
        if (node && node.name === "start") {
          ev.cancel = true;
          return;
        }
      });
      graph.on("afterchange", (ev: EvTypes) => {
        if (ev.action === "add") {
          this.flow?.clearSelected();
          this.nodeId = ev.model.id;
          this.flow?.setSelected(ev.item, true);
        }
      });
    },
    save() {
      const flowData = this.flow?.save();
      console.log(flowData);
    },
    removeEventOptions(eventList: []) {
      if (eventList) {
        eventList.forEach((item) => {
          // delete item.options
        });
      }
    },
    read() {
      // const { props, flow } = JSON.parse(this.contentData)
      // this.flow?.read(flow)
    },
  },
  render() {
    return (
      <div class="flow">
        <Row>
          <Col>
            <div ref="toolbarRef" class="flow-toolbar">
              <ToolbarPannel editor={this.editor} onSave={this.save} />
            </div>
          </Col>
        </Row>
        <Row>
          <Col span={2}>
            <div ref="itemRef" class="flow-item">
              <ItemPannel />
            </div>
          </Col>
          <Col span={17}>
            <div id="page" ref="pageRef" class="flow-item flow-content"></div>
          </Col>
          <Col span={5}>
            <div ref="detailRef" class="flow-item"></div>
          </Col>
        </Row>
      </div>
    );
  },
});
